//用户导入导出等

/**
 * @openapi
 * tags:
 * - name: admin/user
 *   description: 用户数据处理
 */

const router = require("express-promise-router")();


const KindService = require("../services/kind");
const GoodService=require("../services/goods");
const CabinetService=require("../services/cabinet");
const EmoocDevice=require("../services/emooc");
const UserService=require("../services/user");
const ParseHelper=require("../helpers/parse");
const LogService=require("../services/log");
const FileService=require("../services/file");
const config = require("../config/config");
const path = require("path");
const multer = require('multer');
const fs = require("fs");
const fetch = require("node-fetch");
const FormData = require("form-data");
const qiniu = require("../services/qiniu");
const uploadPath = path.join(__dirname, '../../uploads');
const upload = multer({dest: uploadPath});

//获取所有物料种类
/**
 * @openapi
 * /assets/kinds:
 *   post:
 *     tags:
 *       - asset
 *     description: 获取所有物料种类
 *     responses:
 *       200:
 *         description: 成功
 */
router.post('/getCategorys', async function(req, res) {
    const result=await KindService.getCategorys();
    return res.json(result);
});

router.post('/getKindsByCategory', async function(req, res) {
    const category=req.body.category;
    const result=await KindService.getKindsByCategory(category);
    return res.json(result);
}
);

router.post('/getGridKindsByCategory', async function(req, res) {
    const {category,cabinetId}=req.body;
    const result=await KindService.getGridKindsByCategory(category,cabinetId);
    return res.json(result);
});

//根据id获取物料种类
router.post('/kind', async function(req, res) {
    const id=req.body.kindId;
    const result=await KindService.getKindById(id);
    return res.json(result);
}
);

//获取物料种类的网格
router.post('/getGrid', async function(req, res) {
    const {kindId,cabinetId}=req.body;
    const result=await CabinetService.getGrid(kindId,cabinetId);
    return res.json(result);
}
);

//获取有存放物品的柜子
router.post('/getKindGrid', async function(req, res) {
    const {kindId,cabinetId}=req.body;
    const result=await CabinetService.getKindGrid(kindId,cabinetId);
    return res.json(result);
}
);

//在格子上储存物品类别和数量
router.post('/storeItem', async function(req, res) {
    const {cabinetId,grid,boardid,count,kindId,username} = req.body;
    console.log(cabinetId,grid,boardid,count,kindId,username);
    //修改类别的使用数量
    await KindService.change_store_count(kindId,count);
    //存储记录
    await CabinetService.saveTakenRecord(cabinetId,grid,boardid,count,kindId,username,true);
    const result = await CabinetService.storeItem(cabinetId,grid,boardid,count,kindId);
    console.log('存储物品到格子:', result);
    return res.json(result);
});
//打开柜门领取物品
router.post('/takeItem', async function(req, res) {
    const {device,grid,count,kindId,username,cid} = req.body;
    const result = await CabinetService.takeItem(device,grid,cid,count,kindId,username);

    return res.json(result);
});

//根据条码获取物品信息
router.get('/deviceInfo', async (req, res) => {
    const barcode=req.query.c;
    const good=await GoodService.getGoodByBarcode(barcode);
    if(!good){
        res.send({status: "fail", err:'未查询到物品'});
        return
    }
    const bindInfo=await EmoocDevice.getBindInfo(good.deviceId);
    const kind=await KindService.getKindById(good.kindId);
    res.json({good,bindInfo,kind});
});

//绑定硬木设备
router.post('/bind_device', async function(req, res) {
    const {username,barcode} = req.body;
    const _good=await GoodService.getGoodByBarcode(barcode);
    //改变物品的持有人
    const good=await GoodService.change_good_owner(username,_good.barcode);
    //添加设备和人的绑定关系
    const kind=await KindService.getKindById(good.kindId);
    if(kind.category==="个人实验箱"){
        //查看这个用户名下是否绑定过其他的设备，如果有不能绑定
        const userBindInfo=await EmoocDevice.getUserByOwner(username);
        if(userBindInfo){
            res.send({status: "fail", err:'绑定失败：用户已关联其它实验箱，请联系指导教师'});
            return
        }
        //查看这个设备是否已经被绑定,如果被绑定直接解除绑定关系
        await EmoocDevice.unbind_device(good.deviceId);
        const bindInfo=await EmoocDevice.wxBindDevice(good.deviceId,username);
        if(!bindInfo.ok){
            res.send({status: "fail", err:bindInfo.message});
            return
        }    // //存储记录
    }
    const result=await KindService.save_record(good.kindId,good.objectId,username,1,false);
    const _user=await UserService.getUserInfo(username);
    const user=ParseHelper.toJSON(_user);
    LogService.addLog(user,"小程序",`绑定设备：${barcode}`);
    res.json(result);
});

//获取设备码对应的设备信息和位置
router.post('/device_localtion', async function(req, res) {
    const {cabinetId,deviceId} = req.body;
    const good=await GoodService.getGoodByBarcode(deviceId);
    if(!good){
        res.send({status: "fail", err:'未查询到设备'});
        return
    }
    const bindInfo=await KindService.getRecordById(good.objectId);
    const kind=await KindService.getKindById(good.kindId)
    let grid=await CabinetService.getDeviceLocation(cabinetId,good.kindId,kind.occupyCount);
    const occupyCount=kind&&kind.occupyCount?kind.occupyCount:0;
    if(occupyCount&&grid.count>=occupyCount){
        grid=await CabinetService.getEmptyGrid(cabinetId);
    }
    if(!grid){
        grid=await CabinetService.getEmptyGrid(cabinetId);
    }
    return res.json({bindInfo,kind,grid});
});
//归还物品
router.post('/return_good', async function(req, res) {
    const {cabinetId,grid,cid,kind,barcode} = req.body;
    console.log(cabinetId,grid,kind,cid);
    //柜子上物品+1
    await CabinetService.return_good(cabinetId,grid,cid,kind.objectId);
    //解除绑定
    const good=await GoodService.getGoodByBarcode(barcode);
    const kindInfo=await KindService.getKindById(good.kindId);
    if(kindInfo.category==="个人实验箱"){
        await EmoocDevice.unbind_device(good.deviceId);
    }
    //改变物品的持有人
    await GoodService.change_good_owner("admin",barcode);
    //修改存储记录存储记录isReturn=true
    const result=await KindService.save_record(kind.objectId,good.objectId,good.user,1,true);
    //添加规划记录
    await CabinetService.saveTakenRecord(cabinetId,grid,cid,1,kind.objectId,good.user,true)
    return res.json(result);
});

//获取物料柜的格子情况
router.post('/getCabinetGrids', async function(req, res) {
    const cabinetId=req.body.cabinetId;
    const result=await CabinetService.getCabinetGrids(cabinetId);
    return res.json(result);
}
);

//获取物料的类别和种类
router.post('/getCategoryAndKinds', async function(req, res) {
    const result=await KindService.getCategoryAndKinds();
    return res.json(result);
});

//获取预约信息
router.post('/getReservationById', async function(req, res) {
    const bookId = req.body.bookId;
    try {
        const reservation = await KindService.getReservationById(bookId);
        if (!reservation) {
            return res.status(404).json({ error: '预约信息未找到或已领取' });
        }
        return res.json(reservation);
    } catch (error) {
        console.error('获取预约信息失败:', error);
        return res.status(500).json({ error: '获取预约信息失败，请重试' });
    }
});

//检查格子是否有物品
router.post('/checkGridAvailability', async function(req, res) {
    const { kindIds, cabinetId } = req.body;
    try {
        const grids = await KindService.checkGridAvailability(kindIds, cabinetId);
        return res.json({ grids });
    } catch (error) {
        console.error('检查格子可用性失败:', error);
        return res.status(500).json({ error: '检查格子可用性失败，请重试' });
    }
});
//保存柜子的开门记录
router.post('/saveCabinetLog', async function(req, res) {
    const  data  = req.body;
    console.log('保存柜子日志', data);
    const { cabinetId,grid,username,action } = data;
    try {
        const logEntry = await CabinetService.saveCabinetLog(cabinetId,grid,username,action);
        return res.json(logEntry);
    } catch (error) {
        console.error('保存柜子日志失败:', error);
        return res.status(500).json({ error: '保存柜子日志失败，请重试' });
    }
});

//修改格子中物品的数量
router.post('/changeGridStore', async function(req, res) {
    const {gridId,count} = req.body;
    try {
        const result=await KindService.changeGridStore(gridId,count);
        return res.json(result);        
    } catch (error) {
        console.error('修改格子中物品的数量失败:', error);
        return res.status(500).json({ error: '修改格子中物品的数量失败，请重试' });
    }
});

//修改预约借用列表为已领取
router.post('/completeReservation', async function(req, res) {
    const {reservationId} = req.body;
    try {
        const result=await KindService.completeReservation(reservationId);
        return res.json(result);        
    } catch (error) {
        console.error('修改预约借用列表为已领取失败:', error);
        return res.status(500).json({ error: '修改预约借用列表为已领取失败，请重试' });
    }
});

//保存借用记录
router.post('/saveRecord', async function(req, res) {
    const {list,username,type} = req.body;
    try {
        const result=await GoodService.save_record(list,username,type);
        return res.json(result);        
    } catch (error) {
        console.error('保存借用记录失败:', error);
        return res.status(500).json({ error: '保存借用记录失败，请重试' });
    }
});

//根据归还码获取物品信息
router.post('/validateReturnCode', async function(req, res) {
    const { codeData } = req.body;
    try {
        const result = await KindService.validateReturnCode(codeData);
        return res.json(result);
    } catch (error) {
        console.error('根据归还码获取物品信息失败:', error);
        return res.status(500).json({ error: '根据归还码获取物品信息失败，请重试' });
    }
});

//根据维修码获取故障物品信息
router.post('/validateFaultCode', async function(req, res) {
    const { codeData } = req.body;
    try {
        const result = await KindService.validateFaultCode(codeData);
        return res.json(result);
    } catch (error) {
        console.error('根据维修码获取故障物品信息失败:', error);
        return res.status(500).json({ error: '根据维修码获取故障物品信息失败，请重试' });
    }
});


//归还的时候上传图片
router.post('/uploadReturnImage', upload.single('file'), async function(req, res) {
    const { id } = req.body;
    try {
        const file = req.file;
        if (!file) {
            return res.status(400).send({error: "没有找到上传文件"});
        }
        const uploadResult = await _file2url(file);
        const result = await KindService.addImageToBorrowList(id, uploadResult.url);
        res.send({resourceId: result.id});
    } catch (error) {
        console.error('归还的时候上传图片失败:', error);
        return res.status(500).json({ error: '归还的时候上传图片失败，请重试' });
    }
});
//归还的故障物品的时候上传图片
router.post('/uploadFaultImage', upload.single('file'), async function(req, res) {
    const { id } = req.body;
    try {
        const file = req.file;
        if (!file) {
            return res.status(400).send({error: "没有找到上传文件"});
        }
        const uploadResult = await _file2url(file);
        const result = await KindService.addImageToFaultRecord(id, uploadResult.url);
        res.send({resourceId: result.id});
    } catch (error) {
        console.error('归还的时候上传图片失败:', error);
        return res.status(500).json({ error: '归还的时候上传图片失败，请重试' });
    }
});

//把上传的文件存储并得到url
async function _file2url(file){
    const fileserver = config.fileserver;
    const {mimetype, filename, size} = file;
    const originalname = file.originalname || file.name || "";
    var uploadResult = await FileService.saveFileInfo({originalname, mimetype, filename, size});
    uploadResult = ParseHelper.toJSON(uploadResult);
    uploadResult.url = '/file/' + uploadResult.objectId;
    if (fileserver === 'qiniu') {
        const formdata = new FormData();
        const fileLocation = path.join(uploadPath, filename);
        formdata.append('token', qiniu.getUploadToken());
        formdata.append("file", fs.createReadStream(fileLocation));
        await fetch(config.qiniu_upload_url, {method: 'POST', body: formdata})
            .then(res => res.json())
            .then(json => {
                if (json.error) {
                    throw new Error(json.error)
                }
                uploadResult.url = config.qiniu_domain + json.key;
            })
    }
    return uploadResult;
}


//完成归还
router.post('/completeReturn', async function(req, res) {
    const { returnId, grid, cabinetId, kind, count, user } = req.body;
    console.log('完成归还', returnId);
    //柜子上物品+1
    await CabinetService.storeItem(cabinetId, grid.number, grid.cid,count, kind.objectId);
    //修改存储记录存储记录isReturn=true
    await KindService.save_record(kind.objectId, null, null, count, true);
    //添加归还记录
    await CabinetService.saveTakenRecord(cabinetId,grid.number,grid.cid,count,kind.objectId,user,true)
    const result = await KindService.completeReturn(returnId);
    return res.json(result);
});

//故障物品归还
router.post('/completeFault', async function(req, res) {
    const { faultId, grid, cabinetId, kind, count, user } = req.body;
    //将故障物品放到格子中，并记录
    await CabinetService.storeFaultItem(cabinetId, grid.number, grid.cid,count, kind.objectId);
    //修改存储记录存储记录isReturn=true
    await KindService.save_record(kind.objectId, null, null, count, true);
    //添加归还记录
    await CabinetService.saveTakenRecord(cabinetId,grid.number,grid.cid,count,kind.objectId,user,true)
    const result = await KindService.completeFault(faultId,cabinetId,grid.number, grid.cid);
    //将借用列表状态改为未领取
    const faultRecord=await KindService.getFaultRecordById(faultId);
    console.log('faultRecord',faultRecord);
    await KindService.changeBorrowListStatus(faultRecord.listId, "approved");
    return res.json(result);
});

//保存某人拿走了该物品的记录
router.post('/saveTakenRecord', async function(req, res) {
    const {grid,username,cabinetId} = req.body;
    try {
        const result=await CabinetService.saveTakenRecord(cabinetId,grid.number,grid.cid,grid.count,grid.kindId,username,false);
        //如果user是教师，从柜子取走物品之后，要将库存数量加回去
        const _user=await UserService.getUserInfo(username);
        const user=ParseHelper.toJSON(_user);
        if(user.isTeacher||user.isAdmin){
            await KindService.change_kind_used_count(grid.kindId,grid.count,"reduce");
        }
        return res.json(result);        
    } catch (error) {
        console.error('保存记录失败:', error);
        return res.status(500).json({ error: '保存记录失败，请重试' });
    }
});

module.exports = router;
